package com.ruoyi.psi.sale.order.service;


import com.ruoyi.constant.ERPConstant;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.cs.base.customer.domain.CustomerInfo;
import com.ruoyi.cs.base.customer.mapper.CustomerInfoMapper;
import com.ruoyi.personnel.oa.approve.domain.ApproveDomain;
import com.ruoyi.personnel.oa.approve.mapper.ApproveMapper;
import com.ruoyi.personnel.oa.sequence.service.IApproveSequenceService;
import com.ruoyi.produce.process.planself.domain.ProducePlanSelfDto;
import com.ruoyi.produce.process.planself.mapper.ProducePlanSelfMapper;
import com.ruoyi.produce.process.receiving.domain.ReceivingReportDto;
import com.ruoyi.produce.process.receiving.mapper.ReceivingReportMapper;
import com.ruoyi.produce.process.worksheet.domain.ProduceWorkSheet;
import com.ruoyi.produce.process.worksheet.mapper.ProduceWorkSheetMapper;
import com.ruoyi.psi.base.cost.domain.ProductionCostListDto;
import com.ruoyi.psi.base.cost.service.IProductionCostService;
import com.ruoyi.psi.base.product.domain.ProductDto;
import com.ruoyi.psi.base.product.mapper.ProductMapper;
import com.ruoyi.psi.purchase.apply.domain.PurchaseApply;
import com.ruoyi.psi.purchase.apply.mapper.PurchaseApplyMapper;
import com.ruoyi.psi.sale.delivery.domain.*;
import com.ruoyi.psi.sale.delivery.mapper.SaleDeliveryMapper;
import com.ruoyi.psi.sale.delivery.service.ISaleDeliveryService;
import com.ruoyi.psi.sale.order.BI.*;
import com.ruoyi.psi.sale.order.domain.*;
import com.ruoyi.psi.sale.order.mapper.SaleOrderMapper;
import com.ruoyi.utils.ID.IdUtil;
import com.ruoyi.utils.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 销售订单
 * 业务处理层
 */
@Service
public class SaleOrderServiceImpl implements ISaleOrderService {
    @Autowired
    private SaleOrderMapper saleOrderMapper;
    @Autowired
    private ISaleOrderService saleOrderService;
    @Autowired
    private IProductionCostService productionCostService; //产品成本
    @Autowired
    private ISaleDeliveryService saleDeliveryService; //产品出库
    @Autowired
    private SaleDeliveryMapper saleDeliveryMapper;
    @Autowired
    private ProductMapper productMapper; //产品
    @Autowired
    private ProducePlanSelfMapper producePlanSelfMapper; //生产计划
    @Autowired
    private ProduceWorkSheetMapper workSheetMapper; //加工单
    @Autowired
    private IApproveSequenceService approveSequenceService;
    @Autowired
    private ApproveMapper approveMapper;
    @Autowired
    private IdUtil idUtil;
    @Autowired
    private CustomerInfoMapper customerInfoMapper; //客户
    @Autowired
    private PurchaseApplyMapper purchaseApplyMapper; //采购申请
    @Autowired
    private ReceivingReportMapper receivingReportMapper; //验收单


    /**
     * 销售订单查询
     *
     * @param cond
     * @return
     */
    @Override
    public List<SaleOrderDto> selectSaleOrderList(SaleOrderCond cond) {
        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        for (SaleOrderDto s : saleOrderDtos) {
            // 销售总数和总额
            double saleNumberTotal = 0.00;
            double salePriceTotal = 0.00;
            if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(s.getSaleOrderId()))) {
                //存在，则存入销售订单对应产品信息
                List<SaleOrderListDto> saleOrderListDtos = saleOrderMapper.selectSaleOrderListListById(s.getSaleOrderId());
                for (SaleOrderListDto sl : saleOrderListDtos) {
                    sl.setSaleOrderPrice(sl.getSaleUnitPrice() * sl.getSaleOrderNumber()); //销售价格
                    saleNumberTotal += sl.getSaleOrderNumber();
                    salePriceTotal += sl.getSaleUnitPrice() * sl.getSaleOrderNumber();
                    // 某产品的出库数量和某产品的出库金额
                    SaleOrderProductionDeliveryTotal saleOrderProductionDeliveryTotal = saleOrderService.selectSaleProductionDeliveryTotal(sl.getSaleOrderId(), sl.getProduceId());
                    sl.setSaleDeliveryNumber(saleOrderProductionDeliveryTotal.getSaleDeliveryNumber());
                    sl.setSaleDeliveryPrice(saleOrderProductionDeliveryTotal.getSaleDeliveryPrice());
                }
                s.setSaleOrderLists(saleOrderListDtos);
                //出库总数量和出库总金额
                SaleOrderDeliveryTotal saleOrderDeliveryTotal = saleOrderService.selectSaleOrderTotal(s.getSaleOrderId());
                s.setSaleDeliveryPriceTotal(saleOrderDeliveryTotal.getSaleDeliveryPriceTotal());
                s.setSaleDeliveryNumberTotal(saleOrderDeliveryTotal.getSaleDeliveryNumberTotal());
            }
            s.setSaleNumberTotal(saleNumberTotal);
            s.setSalePriceTotal(salePriceTotal);
        }
        return saleOrderDtos;
    }

    /**
     * 按编号查询
     *
     * @param saleOrderId 销售订单编号
     * @return
     */
    @Override
    public SaleOrderDto selectSaleOrderById(String saleOrderId) {
        SaleOrderDto saleOrder = saleOrderMapper.selectSaleOrderById(saleOrderId);
        // 销售总数和总额
        double saleNumberTotal = 0.00;
        double salePriceTotal = 0.00;
        if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(saleOrder.getSaleOrderId()))) {
            //存在，则存入销售订单对应产品信息
            List<SaleOrderListDto> saleOrderListDtos = saleOrderMapper.selectSaleOrderListListById(saleOrder.getSaleOrderId());
            for (SaleOrderListDto sl : saleOrderListDtos) {
                sl.setSaleOrderPrice(sl.getSaleUnitPrice() * sl.getSaleOrderNumber()); //销售价格
                saleNumberTotal += sl.getSaleOrderNumber();
                salePriceTotal += sl.getSaleUnitPrice() * sl.getSaleOrderNumber();
                // 某产品的出库数量和某产品的出库金额
                SaleOrderProductionDeliveryTotal saleOrderProductionDeliveryTotal = saleOrderService.selectSaleProductionDeliveryTotal(sl.getSaleOrderId(), sl.getProduceId());
                sl.setSaleDeliveryNumber(saleOrderProductionDeliveryTotal.getSaleDeliveryNumber());
                sl.setSaleDeliveryPrice(saleOrderProductionDeliveryTotal.getSaleDeliveryPrice());
            }
            saleOrder.setSaleOrderLists(saleOrderListDtos);
            //出库总数量和出库总金额
            SaleOrderDeliveryTotal saleOrderDeliveryTotal = saleOrderService.selectSaleOrderTotal(saleOrder.getSaleOrderId());
            saleOrder.setSaleDeliveryPriceTotal(saleOrderDeliveryTotal.getSaleDeliveryPriceTotal());
            saleOrder.setSaleDeliveryNumberTotal(saleOrderDeliveryTotal.getSaleDeliveryNumberTotal());
        }
        saleOrder.setSaleNumberTotal(saleNumberTotal);
        saleOrder.setSalePriceTotal(salePriceTotal);
        return saleOrder;
    }

    /**
     * 销售订单新增
     *
     * @param saleOrder
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSaleOrder(SaleOrderDomain saleOrder) throws Exception {
        String saleOrderId = idUtil.createSaleOrderId(saleOrder.getSaleOrderType());//自动生成编号
        if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderById(saleOrderId))) {
            //存在
            return 0;
        }
        //不存在
        saleOrder.setSaleOrderId(saleOrderId); //主表添加编号
        ApproveDomain approve = new ApproveDomain(saleOrderId, "销售订单审批", ERPConstant.APPROVAL_TYPE_SALE_ORDER, saleOrder.getStaffSaleId()); //新增审批
        approve.setCurrentApprover(approveSequenceService.getLowestRoleId(ERPConstant.APPROVAL_TYPE_SALE_ORDER));
        approveMapper.insertApprove(approve);
        saleOrderMapper.insertSaleOrder(saleOrder); //销售订单据
        List<SaleOrderListDomain> saleOrderListDomainList = saleOrder.getSaleOrderLists();//销售订单产品信息
        for (int i = 0; i < saleOrderListDomainList.size(); i++) {
            saleOrderListDomainList.get(i).setSaleOrderId(saleOrderId); //子表添加编号
            saleOrderMapper.insertSaleOrderList(saleOrderListDomainList.get(i));//销售订单产品信息
        }
        return 1;

    }

    /**
     * 销售订单更新
     *
     * @param saleOrder
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSaleOrder(SaleOrderDomain saleOrder) throws Exception {
        if (!StringUtils.isNotNull(saleOrderMapper.selectSaleOrderById(saleOrder.getSaleOrderId()))) {
            //不存在
            return 0;
        }
        //存在销售订单单据
        saleOrderMapper.updateSaleOrder(saleOrder);//销售订单单据
        List<SaleOrderListDto> saleOrderListDtos = saleOrderMapper.selectSaleOrderListListById(saleOrder.getSaleOrderId());
//        System.out.println("数据库中查询的数据" + saleOrderListDtos);
        List<SaleOrderListDomain> saleOrderListDomainList = saleOrder.getSaleOrderLists();//销售订单产品信息
//        System.out.println("查询前端传入的修改数据" + saleOrderListDomainList);
        for (int i = 0; i < saleOrderListDomainList.size(); i++) {
            SaleOrderListDto saleOrderListDto = saleOrderMapper.selectSaleOrderListById(saleOrder.getSaleOrderId(), saleOrderListDomainList.get(i).getProduceId());
//            System.out.println("具体的修改对象" + (i + 1) + saleOrderListDto);
            if (StringUtils.isNotNull(saleOrderListDto)) {
                //存在销售订单详细
                for (int j = 0; j < saleOrderListDtos.size(); j++) {
                    if (saleOrderListDtos.get(j).getProduceId().equals(saleOrderListDto.getProduceId())) {
                        saleOrderListDtos.remove(j);//移除新旧都有的部分
                        break;
                    }
                }//更新
//                System.out.println("数据库之后的数据" + (i + 1) + saleOrderLists1);
                saleOrderMapper.updateSaleOrderList(saleOrderListDomainList.get(i));
            } else {//新增
                saleOrderMapper.insertSaleOrderList(saleOrderListDomainList.get(i));
            }
        }
        for (int i = 0; i < saleOrderListDtos.size(); i++) {
            //删除新旧重叠以外的部分
            saleOrderMapper.deleteSaleOrderListById(saleOrderListDtos.get(i).getSaleOrderId(), saleOrderListDtos.get(i).getProduceId());
        }
        return 1;
    }

    /**
     * 更新销售订单删除标志位
     *
     * @param saleOrder
     * @return
     */
    @Override
    public int updateSaleOrderDeleteFlag(SaleOrderDomain saleOrder) {
        if (!StringUtils.isNotNull(saleOrderMapper.selectSaleOrderById(saleOrder.getSaleOrderId()))) {
            //不存在
            return 0;
        }
        saleOrderMapper.updateSaleOrderDeleteFlag(saleOrder);
        List<SaleOrderListDomain> saleOrderLists = saleOrder.getSaleOrderLists();
        // 更新子表的标志位
        if (StringUtils.isNotNull(saleOrderLists)) {
            for (int i = 0; i < saleOrderLists.size(); i++) {
                saleOrderMapper.updateSaleOrderListDeleteFlag(saleOrder.getSaleOrderId(), saleOrderLists.get(i).getProduceId());
            }
        }
        return 1;
    }

    /**
     * 销售订单详细查询
     *
     * @param cond
     * @return
     */
    @Override
    public List<SaleOrderListDto> selectSaleOrderListList(SaleOrderCond cond) {
        List<SaleOrderListDto> saleOrderListDtos = saleOrderMapper.selectSaleOrderListList(cond);
        for (SaleOrderListDto s : saleOrderListDtos) {
            s.setSaleOrderPrice(s.getSaleUnitPrice() * s.getSaleOrderNumber());
        }
        return saleOrderListDtos;
    }

    /**
     * 查询销售订单对应的所有产品详细
     *
     * @param saleOrderId 销售订单编号
     * @return
     */
    @Override
    public List<SaleOrderListDto> selectSaleOrderListListById(String saleOrderId) {
        return saleOrderMapper.selectSaleOrderListListById(saleOrderId);
    }

    /**
     * 查询销售订单对应的指定产品详细
     *
     * @param saleOrderId
     * @param produceId
     * @return
     */
    @Override
    public SaleOrderListDto selectSaleOrderListById(String saleOrderId, String produceId) {
        return saleOrderMapper.selectSaleOrderListById(saleOrderId, produceId);
    }

    /**
     * 查询业务员排行
     * 按时间查询(月)
     *
     * @param cond
     * @return
     */
    @Override
    public List<Salesman> selectSalesman(SaleOrderCond cond) {
        List<Salesman> salesmen = new ArrayList<>(); // 存储业务员的数组
        Map<String, Integer> salesmenMap = new HashMap<>(); // 存储业务员编号的Map

//        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        List<SaleOrderDto> saleOrderDtos = saleOrderService.selectSaleOrderListForBI(cond);
//        System.out.println("销售订单所有数据" + saleOrderDtos);
        // 遍历销售订单，获取相应的数据，存入业务员集合中
        for (int i = 0; i < saleOrderDtos.size(); i++) {
//            System.out.println("第" + i + "个销售订单数据信息" + saleOrderDtos.get(i).getStaffSaleId());
            if (!salesmenMap.containsKey(saleOrderDtos.get(i).getStaffSaleId())) {
                // 新的员工，存入map
                salesmenMap.put(saleOrderDtos.get(i).getStaffSaleId(), i);
                // 创建一个业务员对象
                Salesman salesman = new Salesman();
                salesman.setStaffSaleId(saleOrderDtos.get(i).getStaffSaleId()); //销售员编号
                salesman.setStaffSaleName(saleOrderDtos.get(i).getStaffSaleName()); //销售员名称
                // 销售总数量
                salesman.setSaleNumberTotal(saleOrderDtos.get(i).getSaleNumberTotal());
                // 销售总额
                salesman.setSalePriceTotal(saleOrderDtos.get(i).getSalePriceTotal());
                // 将当前业务员对象加到list集合中
                salesmen.add(salesman);
//                System.out.println("添加成功" + i);
//                System.out.println("当前集合对象" + salesmen);
            } else {
                // 已经存在的员工，累加其销售总数和总额
                Integer integer = salesmenMap.get(saleOrderDtos.get(i).getStaffSaleId());
//                System.out.println("Integer" + integer);
                salesmen.get(integer).setSaleNumberTotal(salesmen.get(integer).getSaleNumberTotal() + saleOrderDtos.get(i).getSaleNumberTotal());
                salesmen.get(integer).setSalePriceTotal(salesmen.get(integer).getSalePriceTotal() + saleOrderDtos.get(i).getSalePriceTotal());
            }
        }
        return salesmen;
    }

    /**
     * 查询订单利润排行
     *
     * @param cond
     * @return
     */
    @Override
    public List<SaleOrderProfit> selectSaleOrderProfit(SaleOrderCond cond) {
        List<SaleOrderProfit> saleOrderProfits = new ArrayList<>(); // 存储订单利润的数组
        // 查询所有销售订单数据
        List<SaleOrderDto> saleOrderDtos = saleOrderService.selectSaleOrderListForBI(cond);
//        System.out.println("所有销售订单数据" + saleOrders);

        // 第一个for循环，遍历所有销售订单数据，目的得到销售订单编号、销售总额数据
        for (SaleOrderDto s : saleOrderDtos) {
            // 创建一个订单利润对象
            SaleOrderProfit saleOrderProfit = new SaleOrderProfit();
            saleOrderProfit.setSaleOrderId(s.getSaleOrderId()); // 销售订单编号
            saleOrderProfit.setSalePriceTotal(s.getSalePriceTotal()); //销售总额
            // 根据销售订单编号获取具体销售产品的信息
            List<SaleOrderListDto> saleOrderListDtos = saleOrderService.selectSaleOrderListListById(s.getSaleOrderId());
//            System.out.println("根据销售订单编号获取具体销售产品的信息" + saleOrderLists);

            double totalCost = 0.00;
            // 第二个for循环，遍历每个销售订单对应的所有产品，目的得到该产品信息
            for (SaleOrderListDto sl : saleOrderListDtos) {
                // 根据产品编号拿到该产品的具体成本来源
                List<ProductionCostListDto> productionCostListDtoList = productionCostService.selectProductionCostListListById(sl.getProduceId());
//                System.out.println("根据产品编号拿到该产品的具体成本来源" + productionCostListDtoList);

                // 第三个for循环，遍历每个产品对应所有的成本费用，目的计算该产品在销售订单中所需要的成本
                double productionCost = 0.00;
                for (ProductionCostListDto c : productionCostListDtoList) {
                    // 该产品具体某项成本项目的费用 * 该产品得到销售数量 = 该产品对应的该成本所需要的成本总价
                    productionCost += c.getCostNumber() * c.getCostUnitPrice() * sl.getSaleOrderNumber();
                }
                // 循环结束 productionCost为该产品在此次销售订单中的总成本
                totalCost += productionCost;
            }
            // 循环结束 totalCost为此次销售订单中的总成本
            saleOrderProfit.setTotalCost(totalCost);
            saleOrderProfit.setTotalProfit(s.getSalePriceTotal() - totalCost); //计算总利润
            // 将当前订单利润对象加到list集合中
            saleOrderProfits.add(saleOrderProfit);
        }
        return saleOrderProfits;
    }

    /**
     * 查询月销售目标达成情况
     *
     * @param cond
     * @return
     */
    @Override
    public List<SaleTargetAchievement> selectSaleTargetAchievement(SaleOrderCond cond) {
        List<SaleTargetAchievement> saleTargetAchievements = new ArrayList<>();
        // 按时间查询所有销售订单信息
        List<SaleOrderDto> saleOrderDtos = saleOrderService.selectSaleOrderListForBI(cond);
        Map<String, SaleTargetAchievement> productMap = new HashMap<>();
        for (SaleOrderDto s : saleOrderDtos) {
            // 遍历销售订单
            List<SaleOrderListDto> saleOrderLists = s.getSaleOrderLists();
            for (SaleOrderListDto sl : saleOrderLists) {
                if (!productMap.containsKey(sl.getProduceId())) { //新产品
                    ProductDto product = productMapper.selectProductById(sl.getProduceId());
                    SaleTargetAchievement saleTargetAchievement = new SaleTargetAchievement(sl.getProduceId(), sl.getProduceName(), product.getMonthlySalesTargetQuantity(), sl.getSaleOrderNumber());
                    productMap.put(sl.getProduceId(), saleTargetAchievement);
                    saleTargetAchievements.add(saleTargetAchievement);
                } else { //已经存在的产品
                    SaleTargetAchievement saleTargetAchievement = productMap.get(sl.getProduceId());
                    Double newActualMonthlySalesQuantity = saleTargetAchievement.getActualMonthlySalesQuantity() + sl.getSaleOrderNumber();//原实际销售数量 + 新实际销售数量
                    saleTargetAchievement.setActualMonthlySalesQuantity(newActualMonthlySalesQuantity);
                }
            }
        }
        return saleTargetAchievements;
    }

    /**
     * 查询订单处理周期
     *
     * @param cond
     * @return
     */
    @Override
    public List<OrderProcessingCycle> selectOrderProcessingCycle(SaleOrderCond cond) {
        List<OrderProcessingCycle> orderProcessingCycleList = new ArrayList<>();
        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        for (int i = 0; i < saleOrderDtos.size(); i++) {
            if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(saleOrderDtos.get(i).getSaleOrderId()))) {
                saleOrderDtos.get(i).setSaleOrderLists(saleOrderMapper.selectSaleOrderListListById(saleOrderDtos.get(i).getSaleOrderId()));
            }
        }
        for (SaleOrderDto s : saleOrderDtos) {
            OrderProcessingCycle orderProcessingCycle = new OrderProcessingCycle();
            orderProcessingCycle.setSaleOrderId(s.getSaleOrderId());
            List<ProducePlanSelfDto> producePlanSelfList = producePlanSelfMapper.selectProducePlanSelfBySaleOrderId(s.getSaleOrderId());//查询该销售订单的生产计划信息
            for (int i = 0; i < producePlanSelfList.size(); i++) {
                orderProcessingCycle.setPlanSelfId(producePlanSelfList.get(i).getPlanSelfId()); //订单相关生产计划编号
                orderProcessingCycle.setOrderProcessingCycleTime(TimeUtil.TimeSubtraction(producePlanSelfList.get(i).getCreateTime(), s.getCreateTime())); //订单处理周期
                orderProcessingCycleList.add(orderProcessingCycle);
            }
        }
        return orderProcessingCycleList;
    }

    /**
     * 查询订单生产周期
     *
     * @param cond
     * @return
     */
    @Override
    public List<OrderProductionCycle> selectOrderProductionCycle(SaleOrderCond cond) {
        List<OrderProductionCycle> orderProductionCycleList = new ArrayList<>();
        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        for (int i = 0; i < saleOrderDtos.size(); i++) {
            if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(saleOrderDtos.get(i).getSaleOrderId()))) {
                saleOrderDtos.get(i).setSaleOrderLists(saleOrderMapper.selectSaleOrderListListById(saleOrderDtos.get(i).getSaleOrderId()));
            }
        }
        for (SaleOrderDto s : saleOrderDtos) {
            OrderProductionCycle orderProductionCycle = new OrderProductionCycle();
            orderProductionCycle.setSaleOrderId(s.getSaleOrderId());
            List<ProducePlanSelfDto> producePlanSelfList = producePlanSelfMapper.selectProducePlanSelfBySaleOrderId(s.getSaleOrderId());//查询该销售订单的生产计划信息
            for (int i = 0; i < producePlanSelfList.size(); i++) {
                List<ProduceWorkSheet> workSheetList = workSheetMapper.selectProduceWorkSheetByPlanSelfId(producePlanSelfList.get(i).getPlanSelfId());//根据生产计划查找加工单
                for (int j = 0; j < workSheetList.size(); j++) {
                    orderProductionCycle.setWorkSheetId(workSheetList.get(j).getWorkSheetId());
                    orderProductionCycle.setOrderReleaseProductionCycle(TimeUtil.TimeSubtraction(workSheetList.get(j).getStartTime(), s.getCreateTime())); //订单生产周期
                    orderProductionCycleList.add(orderProductionCycle);
                }
            }
        }
        return orderProductionCycleList;
    }

    /**
     * 查询订单采购周期
     *
     * @param cond
     * @return
     */
    @Override
    public List<OrderPurchaseCycle> selectOrderPurchaseCycle(SaleOrderCond cond) {
        return null;
    }

    /**
     * 查询订单发货周期
     *
     * @param cond
     * @return
     */
    @Override
    public List<OrderDeliveryCycle> selectOrderDeliveryCycle(SaleOrderCond cond) {
        List<OrderDeliveryCycle> orderDeliveryCycleList = new ArrayList<>();
        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        for (int i = 0; i < saleOrderDtos.size(); i++) {
            if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(saleOrderDtos.get(i).getSaleOrderId()))) {
                saleOrderDtos.get(i).setSaleOrderLists(saleOrderMapper.selectSaleOrderListListById(saleOrderDtos.get(i).getSaleOrderId()));
            }
        }
        for (SaleOrderDto s : saleOrderDtos) {
            OrderDeliveryCycle orderDeliveryCycle = new OrderDeliveryCycle();
            orderDeliveryCycle.setSaleOrderId(s.getSaleOrderId());
            List<SaleDeliveryDto> saleDeliveryList = saleDeliveryMapper.selectSaleDeliveryBySaleOrderId(s.getSaleOrderId());//查询该销售订单的出库记录
            for (int i = 0; i < saleDeliveryList.size(); i++) {
                orderDeliveryCycle.setSaleDeliveryId(saleDeliveryList.get(i).getSaleDeliveryId());
                orderDeliveryCycle.setOrderDeliveryCycleTime(TimeUtil.TimeSubtraction(saleDeliveryList.get(i).getCreateTime(), s.getCreateTime()));
                orderDeliveryCycleList.add(orderDeliveryCycle);
            }
        }
        return orderDeliveryCycleList;
    }

    /**
     * 查询超期订单
     *
     * @param cond
     * @return
     */
    @Override
    public List<SaleOrderDto> selectOverdueOrder(SaleOrderCond cond) {
//        List<SaleOrderDto> orderDtoListNew = new ArrayList<>();
        List<SaleOrderDto> orderDtoListOld = saleOrderMapper.selectSaleOrderList(cond);
        for (SaleOrderDto s : orderDtoListOld) {
            long OrderOverdueTime;
            if (s.getActualDeliveryTime() != null) {
                // 已有出库记录
                OrderOverdueTime = TimeUtil.TimeSubtraction(s.getActualDeliveryTime(), s.getRequiredDeliveryTime());
            } else {
                // 没有出库记录，获取系统当前时间和要求出库时间做对比
                Timestamp date = new Timestamp(new Date().getTime());
                OrderOverdueTime = TimeUtil.TimeSubtraction(date, s.getRequiredDeliveryTime());
            }
            if (OrderOverdueTime < 0) {
                OrderOverdueTime = 0;
            }
            s.setOrderOverdueTime(OrderOverdueTime);
        }
        return orderDtoListOld;
    }

    /**
     * 查询订单成本
     *
     * @param saleOrderId
     * @return
     */
    @Override
    public List<SaleOrderCost> selectSaleOrderCost(String saleOrderId) {
        List<SaleOrderCost> saleOrderCosts = new ArrayList<>(); // 存储订单成本的数组
        // 遍历销售订单，获取相应的数据，存入集合中
        Map<Integer, Integer> saleCostMap = new HashMap<>(); // 存储每个销售订单成本项目编号的Map
        // 查询当前销售订单的销售明细
        List<SaleOrderListDto> saleOrderListDtos = saleOrderService.selectSaleOrderListListById(saleOrderId);
        for (SaleOrderListDto sl : saleOrderListDtos) {
//            System.out.println("当前销售产品" + sl.getProduceId() + "销售数量" + sl.getSaleOrderNumber());
            List<ProductionCostListDto> productionCostListDtoList = productionCostService.selectProductionCostListListById(sl.getProduceId());
            for (int i = 0; i < productionCostListDtoList.size(); i++) {
//                System.out.println("当前第" + (i + 1) + "个成本项目" + productionCostListDtoList.get(i).getCostItemId());
//                ProductionCostListDto productionCostListDto = productionCostService.selectProductionCostListById(sl.getProduceId(), productionCostListDtoList.get(i).getCostItemId());
                double costPrice = productionCostListDtoList.get(i).getCostUnitPrice() * productionCostListDtoList.get(i).getCostNumber();
                if (!saleCostMap.containsKey(productionCostListDtoList.get(i).getCostItemId())) {
                    SaleOrderCost saleOrderCost = new SaleOrderCost(); // 创建一个成本对象
                    saleOrderCost.setSaleOrderId(saleOrderId);

                    saleCostMap.put(productionCostListDtoList.get(i).getCostItemId(), i);

                    saleOrderCost.setCostItemId(productionCostListDtoList.get(i).getCostItemId());
                    saleOrderCost.setCostItemName(productionCostListDtoList.get(i).getCostItemName());
                    saleOrderCost.setCostPrice(costPrice * sl.getSaleOrderNumber());

                    saleOrderCosts.add(i, saleOrderCost);
//                    System.out.println("添加成本项目的次数" + (i + 1) + "成本项目名称" + productionCostListDtoList.get(i).getCostItemName());
//                    System.out.println("当前map中的样子" + saleCostMap);
//                    System.out.println("当前List新增的对象" + saleOrderCosts.get(i));
                } else {
//                    System.out.println("第" + (i+1) + "处发现重复成本项目，开始累加成本，重复成本为" + productionCostListDtoList.get(i).getCostItemId());
                    Integer integer = saleCostMap.get(productionCostListDtoList.get(i).getCostItemId());
//                    System.out.println("集合中integer处的对象" + saleOrderCosts.get(integer));
//                    System.out.println("integer ==" + integer);
                    saleOrderCosts.get(integer).setCostPrice(saleOrderCosts.get(integer).getCostPrice() + costPrice * sl.getSaleOrderNumber());
                }
//                System.out.println("当前成本对象" + saleOrderCost);
//                System.out.println("集合" + saleOrderCosts);
            }
        }
        return saleOrderCosts;
    }

    /**
     * 查询销售订单数量
     *
     * @return
     */
    @Override
    public List<SaleOrderQuantity> selectSaleOrderQuantity() {
        List<SaleOrderQuantity> saleOrderQuantities = saleOrderMapper.selectSaleOrderQuantity();
        for (SaleOrderQuantity item : saleOrderQuantities) {
            List<String> monthList = getMonth(item.getMont());
            List<SaleOrderDto> saleOrderDtos = saleOrderMapper.searchOrderBetweenTime(monthList.get(0), monthList.get(1));
            int count = 0;
            for (int i = 0; i < saleOrderDtos.size(); i++) {
                count++;
            }
            if (count == 0) {
                item.setGrowth(100);
            } else {
                item.setGrowth((float) (item.getOrderQuantities() - count) / count);
            }
        }
        return saleOrderQuantities;
    }

    /**
     * 查询对应的销售订单在销售出库中的出库数量
     *
     * @param saleOrderId
     * @return
     */
    @Override
    public SaleOrderDeliveryTotal selectSaleOrderTotal(String saleOrderId) {
        double saleDeliveryNumberTotal = 0.00;
        double saleDeliveryPriceTotal = 0.00;
        List<SaleDeliveryDto> deliveryList = saleDeliveryService.selectSaleDeliveryBySaleOrderId(saleOrderId);
        for (SaleDeliveryDto s : deliveryList) {
            saleDeliveryNumberTotal += s.getSaleDeliveryNumberTotal();
            saleDeliveryPriceTotal += s.getSaleDeliveryPriceTotal();
        }
        return new SaleOrderDeliveryTotal(saleDeliveryNumberTotal, saleDeliveryPriceTotal);
    }

    /**
     * 查询销售订单中该产品的出库数量
     *
     * @param saleOrderId
     * @param produceId
     * @return
     */
    @Override
    public SaleOrderProductionDeliveryTotal selectSaleProductionDeliveryTotal(String saleOrderId, String produceId) {
        List<SaleDeliveryDto> deliveryList = saleDeliveryService.selectSaleDeliveryBySaleOrderId(saleOrderId);
        double saleDeliveryNumber = 0.00; //产品的出库数量初始值
        double saleDeliveryPrice = 0.00; //产品的出库金额初始值
        // 第一次遍历，找该销售订单的出库记录
        for (SaleDeliveryDto s : deliveryList) {
            List<SaleDeliveryListDto> saleDeliveryListDtoList = s.getSaleDeliveryLists();
            // 第二次遍历，找该产品对应的出库数量
            if (StringUtils.isNotNull(saleDeliveryListDtoList)) {
                // 非空时
                for (SaleDeliveryListDto sl : saleDeliveryListDtoList) {
                    if (sl.getProduceId().equals(produceId)) {
                        saleDeliveryNumber += sl.getSaleDeliveryNumber();
                        saleDeliveryPrice += sl.getSaleDeliveryPrice();
                    }
                }
            }
        }
        return new SaleOrderProductionDeliveryTotal(saleDeliveryNumber, saleDeliveryPrice);
    }

    /**
     * 销售订单查询
     * BI模块使用，不计算出库数量
     *
     * @param cond
     * @return
     */
    @Override
    public List<SaleOrderDto> selectSaleOrderListForBI(SaleOrderCond cond) {
        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        for (SaleOrderDto s : saleOrderDtos) {
            // 销售总数和总额
            double saleNumberTotal = 0.00;
            double salePriceTotal = 0.00;
            if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(s.getSaleOrderId()))) {
                //存在，则存入销售订单对应产品信息
                List<SaleOrderListDto> saleOrderListDtos = saleOrderMapper.selectSaleOrderListListById(s.getSaleOrderId());
                for (SaleOrderListDto sl : saleOrderListDtos) {
                    sl.setSaleOrderPrice(sl.getSaleUnitPrice() * sl.getSaleOrderNumber()); //销售价格
                    saleNumberTotal += sl.getSaleOrderNumber();
                    salePriceTotal += sl.getSaleUnitPrice() * sl.getSaleOrderNumber();
                }
                s.setSaleOrderLists(saleOrderListDtos);
            }
            s.setSaleNumberTotal(saleNumberTotal);
            s.setSalePriceTotal(salePriceTotal);
        }
        return saleOrderDtos;
    }

    /**
     * 查询产品订单数
     *
     * @return
     */
    @Override
    public List<SaleOrderProduct> selectProductOrderMonth() {
        //查所有子表数据
        List<ProductOrderQuantity> productOrderQuantityList = saleOrderMapper.selectProductOrderMonth();

        //产品去重
        Set<String> productSet = new LinkedHashSet<>(); //用HashSet顺序会乱掉
        for (ProductOrderQuantity s : productOrderQuantityList) {
            if (!productSet.contains(s.getProduceId())) {
                productSet.add(s.getProduceId());
            }
        }
//        System.out.println("monthSet=========" + monthSet);

        List<SaleOrderProduct> saleOrderProductList = new ArrayList<>(); //主表返回类
        for (String produceId : productSet) {
            //主表添加属性
            SaleOrderProduct saleOrderProduct = new SaleOrderProduct();
            saleOrderProduct.setProduceId(produceId);
            saleOrderProduct.setProduceName(productMapper.selectProductById(produceId).getProduceName());
            saleOrderProductList.add(saleOrderProduct);
        }
//        System.out.println("saleOrderMonthList=========" + saleOrderMonthList);

        for (int i = 0; i < saleOrderProductList.size(); i++) {
            Map<String, ProductOrderQuantityList> monthMap = new HashMap<>(); //用于产品月份去重
            List<ProductOrderQuantityList> productOrderQuantityLists = new ArrayList<>(); //创子表集合
            for (int j = 0; j < productOrderQuantityList.size(); j++) {
//                System.out.println("productOrderQuantityList=========" + productOrderQuantityList);
                if (saleOrderProductList.get(i).getProduceId().equals(productOrderQuantityList.get(j).getProduceId())) { //产品相同
                    if (!monthMap.containsKey(productOrderQuantityList.get(j).getMont())) {
                        ProductOrderQuantityList list = new ProductOrderQuantityList();
                        list.setMont(productOrderQuantityList.get(j).getMont()); //子表设置月份
                        list.setSaleOrderNumber(productOrderQuantityList.get(j).getSaleOrderNumber()); //子表设置销售数量
                        monthMap.put(productOrderQuantityList.get(j).getMont(), list);
                        productOrderQuantityLists.add(list);
//                        System.out.println("月份" + saleOrderMonthList.get(i).getMont() + "此时的子表productOrderQuantityLists" + productOrderQuantityLists);
                    } else {
                        ProductOrderQuantityList list = monthMap.get(productOrderQuantityList.get(j).getMont());
                        list.setSaleOrderNumber(list.getSaleOrderNumber() + productOrderQuantityList.get(j).getSaleOrderNumber());
                        monthMap.replace(productOrderQuantityList.get(j).getMont(), list);
//                        productOrderQuantityLists.add(list);
//                        System.out.println("修改成功" + list);
                    }
                }
            }
//            System.out.println("productMap222222222" + productMap);
//            System.out.println("添加的子表11111111111" + productOrderQuantityLists);
            saleOrderProductList.get(i).setProductOrderQuantityLists(productOrderQuantityLists); //主表添加子表
        }

        List<String> upMonth = getUpMonth(6); //获取当前时间前6个月时间
        for (int i = 0; i < saleOrderProductList.size(); i++) {
            List<String> monthList = new ArrayList<>(); //每个产品的销售月份集合
//            System.out.println("传入的对象" + saleOrderProductList);
//            System.out.println("第一个size" + saleOrderProductList.size());
            if (StringUtils.isNotNull(saleOrderProductList.get(i).getProductOrderQuantityLists())) {
                List<ProductOrderQuantityList> productOrderQuantityLists = saleOrderProductList.get(i).getProductOrderQuantityLists();
//                System.out.println("当前产品s" + saleOrderProductList.get(i).getProduceId() + "的子表" + saleOrderProductList.get(i).getProductOrderQuantityLists());
                for (int j = 0; j < productOrderQuantityLists.size(); j++) {
                    monthList.add(productOrderQuantityLists.get(j).getMont());
                }

                List<String> stringList = removeSameElement(upMonth, monthList); //此时是相差的月份，这些月份需要赋0

//                System.out.println("当前产品" + saleOrderProductList.get(i).getProduceId() + "相差月份" + stringList);
                for (int j = 0; j < stringList.size(); j++) {
                    ProductOrderQuantityList list = new ProductOrderQuantityList();
                    list.setMont(stringList.get(j)); //子表设置月份
                    list.setSaleOrderNumber(0); //子表设置销售数量
                    productOrderQuantityLists.add(list); //添加新的数组
                }
            }
            sortArrayList(saleOrderProductList.get(i).getProductOrderQuantityLists()); //子表排序
        }
        return saleOrderProductList;
    }

    /**
     * 通过销售订单查询销售订单进度
     * 1-未准备
     * 2-采购中
     * 3-生产加工中
     * 4-生产完成
     * 5-出库
     * @param saleOrderId
     * @return
     */
    @Override
    public int querySaleOrderProgress(String saleOrderId) {
        int res = 0; //默认返回值，用来做判断的
        // 寻找采购情况
        List<PurchaseApply> purchaseApplies = purchaseApplyMapper.selectPurchaseApplyBySaleOrderId(saleOrderId);
        if (purchaseApplies.size() == 0) {
            res = 1;
        } else {
            res = 2;
        }
        // 寻找生产情况
        SaleOrderDto saleOrder = saleOrderService.selectSaleOrderById(saleOrderId);
        double saleNumberTotal = saleOrder.getSaleNumberTotal();
        double productionNumber = 0;
        List<ProducePlanSelfDto> planSelfs = producePlanSelfMapper.selectProducePlanSelfBySaleOrderId(saleOrderId);
        for (ProducePlanSelfDto plan : planSelfs) {
            List<ProduceWorkSheet> produceWorkSheets = workSheetMapper.selectProduceWorkSheetByPlanSelfId(plan.getPlanSelfId());
            for (ProduceWorkSheet workSheet : produceWorkSheets) {
                List<ReceivingReportDto> receivingReports = receivingReportMapper.selectReceivingReportByWorkSheetId(workSheet.getWorkSheetId());
                for (ReceivingReportDto receiving : receivingReports) {
                    productionNumber += receiving.getReceivingReportNumber() - receiving.getUnqualifiedNumber();
                }
            }
        }
        if (productionNumber < saleNumberTotal) {
            res = 3;
        } else {
            res = 4;
        }
        // 寻找出库情况
        List<SaleDeliveryDto> saleDeliveryDtos = saleDeliveryMapper.selectSaleDeliveryBySaleOrderId(saleOrderId);
        if (!saleDeliveryDtos.isEmpty()) {
            res = 5;
        }
        return res;
    }

    /**
     * 查询客户订单
     *
     * @param cond
     * @return
     */
    @Override
    public List<CustomerOrder> selectCustomerOrder(SaleOrderCond cond) {
        List<CustomerOrder> customerOrderList = new ArrayList<>(); // 返回类数组
        Set<String> customerIdSet = new HashSet<>(); //客户编号的集合（用于去重）
        List<SaleOrderDto> saleOrderDtos = saleOrderMapper.selectSaleOrderList(cond);
        for (SaleOrderDto s : saleOrderDtos) {
            while (!customerIdSet.contains(s.getCustomerInfoId())) {
                //当集合中不存在客户编号时，将客户放到集合中
                customerIdSet.add(s.getCustomerInfoId());
            }
        }
        // 遍历客户编号集合
        for (String customerInfoId : customerIdSet) {
            CustomerOrder customerOrder = new CustomerOrder(); // new一个客户订单对象
            List<CustomerOrderList> customerOrderLists = new ArrayList<>(); // new一个子表集合
            customerOrder.setCustomerInfoId(customerInfoId); //主表添加客户编号
            CustomerInfo customerInfo = customerInfoMapper.selectCustomerInfoById(customerInfoId);
            customerOrder.setCustomerInfoName(customerInfo.getCustomerInfoName()); //主表添加客户名称
            customerOrder.setCustomerInfoLevel(customerInfo.getCustomerInfoLevel()); //主表添加客户等级
            //根据客户编号查询该客户编号的所有销售订单
            List<SaleOrderDto> saleOrderListByCustomerId = saleOrderMapper.selectSaleOrderByCustomerId(customerInfoId);
//            System.out.println("大小" + saleOrderListByCustomerId.size());
            for (SaleOrderDto s : saleOrderListByCustomerId) {
                // 销售总数
                double saleNumberTotal = 0.00;
                double salePriceTotal = 0.00;
                if (StringUtils.isNotNull(saleOrderMapper.selectSaleOrderListListById(s.getSaleOrderId()))) {
                    //存在，则存入销售订单对应产品信息
                    List<SaleOrderListDto> saleOrderListDtos = saleOrderMapper.selectSaleOrderListListById(s.getSaleOrderId());
                    for (SaleOrderListDto sl : saleOrderListDtos) {
                        sl.setSaleOrderPrice(sl.getSaleUnitPrice() * sl.getSaleOrderNumber()); //销售价格
                        saleNumberTotal += sl.getSaleOrderNumber();
                        salePriceTotal += sl.getSaleUnitPrice() * sl.getSaleOrderNumber();
                    }
                }
                CustomerOrderList customerOrderListObj = new CustomerOrderList(); //new一个客户订单对象的子表
                customerOrderListObj.setSaleOrderId(s.getSaleOrderId()); // 子表添加销售订单
                customerOrderListObj.setSaleNumberTotal(saleNumberTotal); // 子表添加销售总额
                customerOrderListObj.setSalePriceTotal(salePriceTotal);
                customerOrderLists.add(customerOrderListObj); //子表集合添加子表对象
            }
            customerOrder.setCustomerOrderLists(customerOrderLists); // 主表添加子表集合
            customerOrderList.add(customerOrder); //返回类数组添加主表对象
        }
        return customerOrderList;
    }

    /**
     * 获取当前时间的前月份
     * @param num
     * @return
     */
    //本月和前num个月一共(num+1)个月的时间
    public List<String> getUpMonth(int num) {
        Date now = new Date();
        List<String> list=new ArrayList<>();
        for (int i = 1; i <= num; i++) {
            Date newDate11 = stepMonth(now, -(num-i));
            SimpleDateFormat y1 = new SimpleDateFormat("yyyy-MM"); //年
            String format = y1.format(newDate11);
            list.add(format);
        }
        return list;

    }

    //获取前month个月的时间
    public Date stepMonth(Date sourceDate, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }

    /**
     * 去除两个数组中的相同元素
     * @param stringStr1
     * @param stringStr2
     * @return
     */
    public List<String> removeSameElement(List<String> stringStr1, List<String> stringStr2) {
        Set<String> stringSet = new LinkedHashSet<>();
        stringSet.addAll(stringStr1);
//        System.out.println("用于对比的数组集合" + stringStr2);
        for (int i = 0; i < stringStr2.size(); i++) {
//            System.out.println("进去了" + stringStr2.get(i));
            if (stringSet.contains(stringStr2.get(i))) {
                // 如果第二个中的该元素在第一个中存在，说明两个共有
                stringSet.remove(stringStr2.get(i));
            }
        }
        List<String> list = new ArrayList<>();
//        System.out.println("去重之后的set集合" + set1);
        for (String str : stringSet) {
            list.add(str);
        }
        return list;
    }

    /**
     * 字符串数组排序
     */
    public void sortArrayList(List<ProductOrderQuantityList> productOrderQuantityLists) {
        productOrderQuantityLists.sort(new Comparator<ProductOrderQuantityList>() {
            @Override
            public int compare(ProductOrderQuantityList o1, ProductOrderQuantityList o2) {
                return o1.getMont().compareTo(o2.getMont());
            }
        });
    }

    /**
     * 获取指定月份的前一个月时间
     * @param month
     * @return
     */
    public List<String> getMonth(String month) {
        List<String> monthList = new ArrayList<>();
        String m = searchLastMonth(month);
        String days = searchDayByMonth(m);
        monthList.add(m + "-01 00:00:00");
//        monthList.add(month + "-01 00:00:00");
        monthList.add(m + "-" + days + " 00:00:00");
        return monthList;
    }

    /**
     * 根据月份返回当月天数
     * @param month
     * @return
     */
    public String searchDayByMonth(String month) {
        String m = month.substring(5, 7);
        String res = "";
        switch (m) {
            case "01":
                res = "31";
                break;
            case "02":
                res = "28";
                break;
            case "03":
                res = "31";
                break;
            case "04":
                res = "30";
                break;
            case "05":
                res = "31";
                break;
            case "06":
                res = "30";
                break;
            case "07":
                res = "31";
                break;
            case "08":
                res = "31";
                break;
            case "09":
                res = "30";
                break;
            case "10":
                res = "31";
                break;
            case "11":
                res = "30";
                break;
            case "12":
                res = "31";
                break;
        }
        return res;
    }

    /**
     * 获取当月的上一个月
     * @param month
     * @return 2022-03
     */
    public String searchLastMonth(String month) {
        String y = month.substring(0, 4);
        int i = Integer.parseInt(y);
        String lastYear = String.valueOf(i - 1);
        String m = month.substring(5, 7);
        String res = "";
        switch (m) {
            case "01":
                res = lastYear +"-12";
                break;
            case "02":
                res = y + "-01";
                break;
            case "03":
                res = y + "-02";
                break;
            case "04":
                res = y + "-03";
                break;
            case "05":
                res = y + "-04";
                break;
            case "06":
                res = y + "-05";
                break;
            case "07":
                res = y + "-06";
                break;
            case "08":
                res = y + "-07";
                break;
            case "09":
                res = y + "-08";
                break;
            case "10":
                res = y + "-09";
                break;
            case "11":
                res = y + "-10";
                break;
            case "12":
                res = y + "-11";
                break;
        }
        return res;
    }
}
